package ejb;

import Entities.Mesa;
import Entities.Reserva;
import ejb.soportes.Consulta;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class ReservaFacade extends FacadeAbstracto<Reserva> implements ReservaFacadeLocal {

    @PersistenceContext(unitName = "SGR-ejbPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public ReservaFacade() {
        super(Reserva.class);
    }

    @Override
    public List<Reserva> buscarReservas(int maximo) {
        Query q = em.createNamedQuery("todasReservas");
        List<Reserva> listaReservas = q.getResultList();
        return listaReservas;
    }

    @Override
    public boolean reservar(Reserva reserva) {
        boolean resultado;
        int anio_ = reserva.getFechaHora().get(Calendar.YEAR);
        int mes_ = reserva.getFechaHora().get(Calendar.MONTH) + 1;
        int dia_ = reserva.getFechaHora().get(Calendar.DAY_OF_MONTH);
        String fecha = anio_ + "-" + mes_ + "-" + dia_;
        try {
            Query query = em.createNativeQuery("Select m.id from mesa m where m.ACTIVO = true and "
                    + "m.MAXIMO >= " + reserva.getCantidad() + " and m.MINIMO <= " + reserva.getCantidad()
                    + " and m.id not in (Select rm.listaMesas_id from reserva_mesa rm INNER JOIN "
                    + "reserva r on rm.Reserva_ID = r.ID and r.FECHAHORA = '" + fecha
                    + "' and r.HORARIO = " + reserva.getHorario() + ") limit 1");
            int idMesa = (int) query.getSingleResult();
            if (idMesa != 0) {
                Query q = em.createQuery("Select m from Mesa m where m.id = " + idMesa);
                Mesa m = (Mesa) q.getSingleResult();
                List<Mesa> lm = new ArrayList();
                lm.add(m);
                reserva.setListaMesas(lm);
                getEntityManager().merge(reserva);
                resultado = true;
            } else {
                resultado = false;
            }
        } catch (Exception e) {
            resultado = false;
        }
        return resultado;
    }

    @Override
    public List<Object> mesasSeleccionadas(Reserva reserva) {
        List<Object> listaId = new ArrayList();
        try {
            int anio_ = reserva.getFechaHora().get(Calendar.YEAR);
            int mes_ = reserva.getFechaHora().get(Calendar.MONTH) + 1;
            int dia_ = reserva.getFechaHora().get(Calendar.DAY_OF_MONTH);
            String fecha = anio_ + "-" + mes_ + "-" + dia_;
            Query query = em.createNativeQuery("Select m.id from mesa m where m.ACTIVO = true and "
                    + "m.MAXIMO >= " + reserva.getCantidad() + " and m.MINIMO <= " + reserva.getCantidad()
                    + " and m.id in (Select rm.listaMesas_id from reserva_mesa rm INNER JOIN "
                    + "reserva r on rm.Reserva_ID = r.ID and r.FECHAHORA = '" + fecha
                    + "' and r.HORARIO = " + reserva.getHorario() + ")");
            listaId = query.getResultList();
        } catch (Exception e) {
        }
        return listaId;
    }

    @Override
    public List<Mesa> mesasParaReservar(Reserva reserva) {
        List<Mesa> resultado = new ArrayList();
        List<Integer> listaId = new ArrayList();
        try {
            int anio_ = reserva.getFechaHora().get(Calendar.YEAR);
            int mes_ = reserva.getFechaHora().get(Calendar.MONTH) + 1;
            int dia_ = reserva.getFechaHora().get(Calendar.DAY_OF_MONTH);
            String fecha = anio_ + "-" + mes_ + "-" + dia_;
            if (reserva.getHorario() != 0) {
                Query query = em.createNativeQuery("Select m.id from mesa m where m.ACTIVO = true and "
                        + "m.MAXIMO >= " + reserva.getCantidad() + " and m.MINIMO <= " + reserva.getCantidad()
                        + " and m.id not in (Select rm.listaMesas_id from reserva_mesa rm INNER JOIN "
                        + "reserva r on rm.Reserva_ID = r.ID and r.FECHAHORA = '" + fecha
                        + "' and r.HORARIO = " + reserva.getHorario() + ")");
                listaId = query.getResultList();
                for (Integer id : listaId) {
                    Mesa m = new Mesa();
                    m.setId(id);
                    Consulta c = new Consulta(m);
                    c.NUMERO_NULO = 0;
                    m.setMaximo(0);
                    m.setMinimo(0);
                    List<Condicional> condiciones = new ArrayList();
                    condiciones.add(new Condicional("maximo", reserva.getCantidad(), ">="));
                    condiciones.add(new Condicional("minimo", reserva.getCantidad(), "<="));
                    c.setCondicionales(condiciones);
                    m = (Mesa) consultarSimpleResult(c, new int[]{0, 1});
                    resultado.add(m);
                }
            }
        } catch (Exception e) {
        }
        return resultado;
    }

    private List ejecutarConsulta(String consulta, int[] rango) throws Exception {
        javax.persistence.Query q = getEntityManager().createQuery(consulta);
        if (rango[0] >= 0 && rango[1] >= 0) {
            q.setMaxResults(rango[1] - rango[0]);
            q.setFirstResult(rango[0]);
        }
        return q.getResultList();
    }

    private Object consultarSimpleResult(Consulta consulta, int[] rango) throws Exception {
        List objs = consultar(consulta, rango);
        if (objs != null) {
            if (objs.size() > 0) {
                return objs.get(0);
            }
        }
        return null;
    }

    private List consultar(Consulta consulta, int[] rango) throws Exception {
        return ejecutarConsulta(consulta.toString(), rango);
    }
}
